﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using iDMS.Models;
using System.Web.Security;

namespace iDMS.Controllers
{

    public class EmployeeController : Controller
    {

        //
        // GET: /Employee/


        private List<SelectListItem> populateEntity<T>(IQueryable<T> entity, string dataValueField, string dataTextField)
        {
            List<SelectListItem> result = new List<SelectListItem>();
            SelectList sl = new SelectList(entity.ToList(), dataValueField, dataTextField);
            return sl.ToList();
        }

        private List<SelectListItem> populateGender()
        {
            List<SelectListItem> result = new List<SelectListItem>();
            result.Add(new SelectListItem() { Text = "Female", Value = "F" });
            result.Add(new SelectListItem() { Text = "Male", Value = "M" });
            return result;
        }

        private List<SelectListItem> populateDepartments(int excludeId)
        {
            List<SelectListItem> list = new List<SelectListItem>();
            SelectListItem nullItem = new SelectListItem();
            nullItem.Value = "0";
            nullItem.Text = "No one";
            list.Add(nullItem);
            list.AddRange(populateEntity(db.DepartmentsGetAll().Where(d => d.DepartmentID != excludeId), "DepartmentID", "FullName2"));
            return list;
        }

        

        private List<SelectListItem> populateEmployees()
        {
            return populateEntity(db.EmployeesGetAll(), "EmployeeID", "FullName");
        }

        DMSRepository db = new DMSRepository();
        [CustomAuthorize(Roles = "Normal User")]
        public ActionResult Index()
        {

            return View(db.EmployeesGetAll());
        }

        [CustomAuthorize(Roles = "Normal User")]
        public ActionResult Departments()
        {
            var departments = db.DepartmentsGetAll();
            departments = departments.Where(d => d.DepartmentParentID == null);
            return View(departments);
        }

        [CustomAuthorize(Roles = "Normal User")]
        public ActionResult Department(int id)
        {
            Department model = db.DepartmentsGetAll().Where(d => d.DepartmentID == id).SingleOrDefault();
            if (model == null)
            {
                return HttpNotFound();
            }
            ViewBag.Employees = db.EmployeesGetAll().Where(e => e.DepartmentID == id).ToList();
            ViewBag.ChildDepartments = db.DepartmentsGetAll().Where(d => d.DepartmentParentID == id).ToList();
            if (model.DepartmentParentID == null)
            {
                ViewBag.isTopLevel = true;
            }
            else
            {
                ViewBag.isTopLevel = false;
            }
            return View(model);
        }

        [CustomAuthorize(Roles = "Administrator")]
        public ActionResult DepartmentCreate()
        {
            ViewBag.Departments = populateDepartments(0);
            ViewBag.Employees = populateEmployees();
            return View();
        }

        [HttpPost]
        [CustomAuthorize(Roles = "Administrator")]
        public ActionResult DepartmentCreate(Department model)
        {
            ViewBag.Departments = populateDepartments(0);
            ViewBag.Employees = populateEmployees();
            if (ModelState.IsValid)
            {
                model.LastModified = DateTime.Now;
                bool succeded;
                if (model.DepartmentParentID == 0)
                {
                    model.DepartmentParentID = null;
                }
                try
                {
                    db.DepartmentsAdd(model);
                    db.CommitChanges();
                    succeded = true;
                }
                catch (Exception)
                {
                    ModelState.AddModelError("", Messages.errorDBUpdate);
                    succeded = false;
                }
                if (succeded)
                {
                    return RedirectToAction("Departments");
                }
                else
                {
                    ModelState.AddModelError("", Messages.errOcured);
                }
            }            
            return View(model);
        }

        [CustomAuthorize(Roles = "Administrator")]
        public ActionResult DepartmentEdit(int id)
        {
            Department model = db.DepartmentsGetAll().SingleOrDefault(d => d.DepartmentID == id);
            if (model == null)
            {
                return HttpNotFound();
            }
            if (model.DepartmentParentID == null)
            {
                model.DepartmentParentID = 0;
            }
            ViewBag.Departments = populateDepartments(id);
            ViewBag.Employees = populateEmployees();
            
            return View(model);
        }
        
        [HttpPost]
        [CustomAuthorize(Roles = "Administrator")]
        public ActionResult DepartmentEdit(int id, FormCollection collection)
        {
            Department model = db.DepartmentsGetAll().SingleOrDefault(d => d.DepartmentID == id);
            if (model == null)
            {
                return HttpNotFound();
            }
            if (ModelState.IsValid)
            {
                bool succeded;
                try
                {
                    UpdateModel(model);
                    model.LastModified = DateTime.Now;
                    if (model.DepartmentParentID == 0)
                    {
                        model.DepartmentParentID = null;
                    }
                    db.CommitChanges();
                    succeded = true;

                }
                catch (Exception e)
                {
                    ModelState.AddModelError("", e.Message);
                    succeded = false;
                }
                if (succeded)
                {
                    return RedirectToAction("Departments");
                }
                else
                {
                    ModelState.AddModelError("", Messages.errOcured);
                } 
            }

            ViewBag.Departments = populateDepartments(id);
            ViewBag.Employees = populateEmployees();
            if (model.DepartmentParentID == null)
            {
                model.DepartmentParentID = 0;
            }
            return View(model);
        }

        //
        // GET: /Employee/Details/5
        [CustomAuthorize(Roles = "Normal User")]
        public ActionResult Details(int id)
        {
            Employee model = db.EmployeesGetAll().SingleOrDefault(e => e.EmployeeID == id);
            if (model == null)
            {
                return HttpNotFound();
            }


            Department dep = db.DepartmentsGetAll().SingleOrDefault(d => d.DepartmentID == model.DepartmentID);

            ViewBag.Supervisor = dep.Employee;
            return View(model);
        }

        [CustomAuthorize(Roles = "Normal User")]
        public ActionResult DetailsWindow(int id)
        {
            Employee model = db.EmployeesGetAll().SingleOrDefault(e => e.EmployeeID == id);
            if (model == null)
            {
                return Content("Employee Not Found", "text/html");
            }

            Department dep = db.DepartmentsGetAll().SingleOrDefault(d => d.DepartmentID == model.DepartmentID);

            ViewBag.Supervisor = dep.Employee;

            return PartialView("_DetailsWindowGUID", model);
        }

        [CustomAuthorize(Roles = "Normal User")]
        public ActionResult DetailsWindowGUID(Guid id)
        {
            Employee model = db.EmployeesGetAll().SingleOrDefault(e => e.UserGUID == id);
            if (model == null)
            {
                return Content("Employee Not Found", "text/html");
            }


            Department dep = db.DepartmentsGetAll().SingleOrDefault(d => d.DepartmentID == model.DepartmentID);

            ViewBag.Supervisor = dep.Employee;

            return PartialView("_DetailsWindowGUID", model);
        }
        [CustomAuthorize(Roles = "Normal User")]
        public ActionResult DetailsFromUser(Guid id)
        {
            Employee model = db.EmployeesGetAll().SingleOrDefault(e => e.UserGUID == id);
            if (model == null)
            {
                return RedirectToAction("Register");
            }

            ViewBag.UserName = Membership.GetUser(id).UserName;

            Department dep = db.DepartmentsGetAll().SingleOrDefault(d => d.DepartmentID == model.DepartmentID);

            ViewBag.Supervisor = dep.Employee;

            return View(model);
        }

        //
        // GET: /Employee/Edit/5
        [CustomAuthorize(Roles = "Administrator")]
        public ActionResult Edit(int id)
        {
            Employee model = db.EmployeesGetAll().SingleOrDefault(e => e.EmployeeID == id);
            if (model == null)
            {
                return HttpNotFound();
            }
            ViewBag.Departments = populateEntity(db.DepartmentsGetAll().OrderBy(d => d.ShortName), "DepartmentID", "FullName2");
            ViewBag.Genders = populateGender();
            return View(model);
        }

        //
        // POST: /Employee/Edit/5

        [HttpPost]
        [CustomAuthorize(Roles = "Administrator")]
        public ActionResult Edit(int id, FormCollection collection)
        {
            Employee model = db.EmployeesGetAll().SingleOrDefault(e => e.EmployeeID == id);
            if (model == null)
            {
                return HttpNotFound();
            }
            ViewBag.Departments = populateEntity(db.DepartmentsGetAll().OrderBy(d => d.ShortName), "DepartmentID", "FullName2");
            ViewBag.Genders = populateGender();
            bool succeded;
            try
            {
                UpdateModel(model);
                model.LastModified = DateTime.Now;
                db.CommitChanges();
                succeded = true;

            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
                succeded = false;
            }
            if (succeded)
            {
                return RedirectToAction("Index");
            }
            else
            {
                ModelState.AddModelError("", Messages.errOcured);
            }
            return View(model);
        }



        public ActionResult Register()
        {
            ViewBag.Departments = populateEntity(db.DepartmentsGetAll().OrderBy(d => d.ShortName), "DepartmentID", "FullName2");
            ViewBag.Genders = populateGender();
            return View();
        }

        [HttpPost]
        public ActionResult Register(Employee model)
        {
            ViewBag.Departments = populateEntity(db.DepartmentsGetAll().OrderBy(d => d.ShortName), "DepartmentID", "FullName2");
            ViewBag.Genders = populateGender();
            //string n = User.Identity.Name;
            MembershipUser u = Membership.GetUser();
            if (ModelState.IsValid && u != null)
            {
                model.UserGUID = (Guid)u.ProviderUserKey;
                model.LastModified = DateTime.Now;
                bool succeded;
                try
                {
                    db.EmployeeAdd(model);
                    db.CommitChanges();
                    succeded = true;
                }
                catch (Exception)
                {
                    ModelState.AddModelError("", Messages.errorDBUpdate);
                    succeded = false;
                }
                if (succeded)
                {
                    //FormsAuthentication.SignOut();
                    
                    return View("Registered", model);
                }
            }
            else
            {
                ModelState.AddModelError("", Messages.errOcured);
            }
            return View(model);
        }

    }
}
